<?php
// 应用公共文件
use think\Request;
use think\response\Json;

const VALIDATE_RULE = [
    "date"      => "/^\d{4}(\/|-|\s|.)\d{1,2}(\/|-|\s|.)\d{1,2}$/",
    "phone"     => "/[1][3,4,5,7,8][0-9]{9}/",
    "mail"      => "/[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/"
];

if(!function_exists("buildWhere")) {
    /**
     * 根据传入得到 $data（格式详见参数介绍） 返回合适的 $where
     * @param Request|array $request
     * @param array $data 数据
     * @example
     *  示例 ["userid"=>"in,id_user","product_id"=>"id_product","in,test","test1"]
     *      1.传入关联数组 键名是需要在 Request 中检索的字段。
     *          (1)如果键值使用 "," 隔开，逗号（英文）之前是 运算符 逗号（英文）之后是在数据库中被搜索的$request索引
     *          (2)如果键值没有使用 "," 隔开，默认使用 “=” 当作运算符，键值作为在数据库中被搜索的$request索引
     *      2.传入 索引数组
     *          (1)如果键值使用 "," 隔开，逗号（英文）之前是 运算符 逗号（英文）之后的字符串 既是在 Request 中检索的字段 也是在数据库中被搜索的$request索引
     *          (2)如果键值没有使用 "," 隔开，默认使用 “=” 当作运算符，键值 既是在 Request 中检索的字段 也是在数据库中被搜索的$request索引
     *  在本例中 搜索 id_user in request["userid"],id_product = request["product_id"],test in request["test"],test1 = request["test1"]
     * @return array
     */
    function buildWhere(Request|array $request, array $data): array
    {
        $where = [];
        //将 $data 键值对 依次放入闭包处理
        array_walk($data,function ($value,$key) use($request,&$where) {
            if(strstr($value,",")) {
                //如果键值里有 逗号（英文）
                $param = explode(",",$value);
            }else {
                //如果键值里没有 逗号（英文）
                $param = ["=",$value];
            }
            if(is_numeric($key)) {
                //如果传入的是索引数组，将值赋给键，键将用于在 $request 中检索
                $key = $param[1];
            }
            if("" != $request[$key]) {
                //如果 $request 中存在 $key
                if("null" == $request[$key]) {
                    $where[] = [$param[1],"null"];
                }else if("like" == $param[0]){
                    //如果运算符是 like 则要给 $request[$key] (将在被数据库中搜索的字段)加上通配符
                    $where[] = [$param[1],$param[0],"%".$request[$key]."%"];
                }else {
                    $where[] = [$param[1],$param[0],$request[$key]];
                }
            }
        });
        return $where;
    }
}

if(!function_exists("getMissParam")) {
    /**
     * 检查传入的数据中是否缺失 必填参数
     * @param Request|array $source 传入的数据
     * @param array $requireParam 必填参数
     * @example ["type","user_id","send_id","title","content"]
     * @return array|false
     */
    function getMissParam(Request|array $source, array $requireParam): bool|array
    {
        $missParam = [];
        array_walk($requireParam,function ($value,$key) use ($source,&$missParam){
            if("" == $source[$value]) {
                $missParam[] = $value;
            }
        });
        if([] == $missParam) {
            return false;
        }else {
            return $missParam;
        }
    }
}

if(!function_exists("returnJson")) {

    /**
     * @param int $status 接口状态码 默认返回 500
     * @param string $message 接口返回信息 默认返回空字符串
     * @param mixed $data 接口返回数据 默认返回 false
     * @return Json
     */
    function returnJson(int $status = 500,string $message = "",mixed $data = false): Json
    {
        return json([
            "status"    => $status,
            "message"   => $message,
            "data"      => $data
        ])->code($status);
    }
}

if(!function_exists("validateParam")) {
    /**
     * 检查传入的数据中是否缺失,并验证类型
     * @param Request|array $source 传入的数据
     * @param array $requireParam 必填参数
     * @example [ "roomId" => "array", "startDate" => "date", "endDate" => "date", "top" => "integer" ]
     * @return array|false
     */
    function validateParam(Request|array $source, array $requireParam): bool|array
    {
        $missParam = [];
        $typeError = [];
        foreach ($requireParam as $key => $value) {
            if(!isset($source[$key])) {
                $missParam[] = $key;
            }else {
                if(!dataTypeValidate($source[$key],$value)) {
                    $typeError[] = $key;
                }
            }
        }
        return [
                "missParam"     => $missParam,
                "typeError"    => $typeError
        ];
    }
}

if(!function_exists("dataTypeValidate")) {
    /**
     * 验证数据是否是对应类型
     * @param mixed $data 待验证的数据
     * @param string $type 待验证的类型
     * @return bool
     */
    function dataTypeValidate(mixed $data, string $type): bool
    {
        switch ($type) {
            case "number" :
                return is_numeric($data);
            case "string" :
                return is_string($data);
            case "array" :
                return is_array($data);
            default:
                if(array_key_exists($type,VALIDATE_RULE)) {
                    return preg_match(VALIDATE_RULE[$type],$data);
                }else {
                    return false;
                }
        }
    }
}